/*
 * Main.java
 *
 */
package da5221_lab1_2011;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Scanner;

/**
 *
 * @author Saeid Kazemi Kristianstad University January 2010
 */
public class Main {

    //declaration
    Scanner myScanner;
    int[] sortMeHundredArr;
    int[] sortMeTenThousandArr;
    int[] sortMeMillionArr;
    int[] unSortedHundredArr;
    int[] unSortedTenThousandArr;
    int[] unSortedMillionArr;
    int x;
    //You can have a currentArray variable here
    boolean firstTime;
    boolean sorted; //You can use the boolean firstTime instead.

    /**
     * Creates a new instance of Main
     */
    public Main() {

        //Initialization
        myScanner = new Scanner(System.in);

        sortMeHundredArr = new int[100];
        sortMeTenThousandArr = new int[10000];
        sortMeMillionArr = new int[1000000];

        unSortedHundredArr = new int[100];
        unSortedTenThousandArr = new int[10000];
        unSortedMillionArr = new int[1000000];

        firstTime = true;

        //The method fills the arrays with the numbers form  "milliion.txt""
        fillAllArrays();

        //The arrays are identical before the user sort them, after sorting they are different in the order of contents
    }//End of constructor

    public void myMainMethod() {
        fix f = new fix(sortMeHundredArr, sortMeTenThousandArr, sortMeMillionArr, x);
        fix ff = new fix(unSortedHundredArr, unSortedTenThousandArr, unSortedMillionArr, x);
        while (true) {
            printMenu();


            //Only accepts numbers in range of signed integers. It does not take care of entries other than those numbers.
            switch (myScanner.nextInt()) {

                case 1:
                    System.out.println("Choose an option");
                    System.out.println("1.Get the sorted hundred array");
                    System.out.println("2.Get the sorted ten thousand array");
                    System.out.println("3.Get the sorted million array");

                    switch (myScanner.nextInt()) {

                        case 1:
                            long startTime1 = System.nanoTime();
                            f.sortHundred(sortMeHundredArr);
                            for (int i = 0; i < sortMeHundredArr.length; i++) {
                                System.out.println("Sorted hundred array  " + sortMeHundredArr[i]);
                            }
                            System.out.println("End of sorting one hundred array");
                            long estimatedTime1 = System.nanoTime() - startTime1;

                            System.out.println("The running time is " + estimatedTime1 + "  nanoseconds ");

                            break;
                        case 2:
                            long startTime2 = System.nanoTime();
                            f.sortTenThousand(sortMeTenThousandArr);
                            for (int i = 0; i < sortMeTenThousandArr.length; i++) {
                                System.out.println("Sorted ten thousand array  " + sortMeTenThousandArr[i]);
                            }
                            System.out.println("End of sorting ten thousand array");
                            long estimatedTime2 = System.nanoTime() - startTime2;
                            System.out.println("The running time is " + estimatedTime2 + "  nanoseconds ");
                            break;
                        case 3:
                            long startTime3 = System.nanoTime();
                            f.sortMillion(sortMeMillionArr);
                            for (int i = 0; i < sortMeMillionArr.length; i++) {
                                System.out.println("Sorted million array  " + sortMeMillionArr[i]);
                            }
                            System.out.println("End of sorting million array");
                            long estimatedTime3 = System.nanoTime() - startTime3;
                            System.out.println("The running time is " + estimatedTime3 + "  nanoseconds ");
                            break;
                    }

                    firstTime = false;
                    break;

                case 2:
                    //use "boolean sorted" in line 35 to prevent being activated before sorting
                    chooseArrayMenu();
//                    System.out.println("I'll write the code to find the minimum in the chosen array ");
                    switch (myScanner.nextInt()) {
                        case 1:
                            long startTime4 = System.nanoTime();
                            f.sortHundred(sortMeHundredArr);

                            System.out.println("The minimun of the sorted hundred array is " + sortMeHundredArr[0]);
                            long estimatedTime4 = System.nanoTime() - startTime4;
                            System.out.println("The running time is " + estimatedTime4 + "  nanoseconds ");
                            break;
                        case 2:
                            long startTime5 = System.nanoTime();
                            f.sortTenThousand(sortMeTenThousandArr);

                            System.out.println("the minimun of the sorted ten thousand array is " + sortMeTenThousandArr[0]);
                            long estimatedTime5 = System.nanoTime() - startTime5;
                            System.out.println("The running time is " + estimatedTime5 + "  nanoseconds ");
                            break;
                        case 3:
                            long startTime6 = System.nanoTime();
                            f.sortMillion(sortMeMillionArr);

                            System.out.println("The minimun of the sorted million array is " + sortMeMillionArr[0]);
                            long estimatedTime6 = System.nanoTime() - startTime6;
                            System.out.println("The running time is " + estimatedTime6 + "  nanoseconds ");
                            break;
                        case 4:
                            long startTime7 = System.nanoTime();
                            ff.findMinUnsortedHundred(unSortedHundredArr);
                            System.out.println("The minimum of the unsorted hundred array is " + unSortedHundredArr[0]);
                            long estimatedTime7 = System.nanoTime() - startTime7;
                            System.out.println("The running time is " + estimatedTime7 + "  nanoseconds ");
                            break;
                        case 5:
                            long startTime8 = System.nanoTime();
                            ff.findMinUnsortedTenThousand(unSortedTenThousandArr);
                            System.out.println("The minimum of the unsorted ten thousnad array is " + unSortedTenThousandArr[0]);
                            long estimatedTime8 = System.nanoTime() - startTime8;
                            System.out.println("The running time is " + estimatedTime8 + "  nanoseconds ");
                            break;
                        case 6:
                            long startTime9 = System.nanoTime();
                            ff.findMinUnsortedMillion(unSortedMillionArr);
                            System.out.println("The minimum of the unsorted hundred array is " + unSortedMillionArr[0]);
                            long estimatedTime9 = System.nanoTime() - startTime9;
                            System.out.println("The running time is " + estimatedTime9 + "  nanoseconds ");
                            break;
                    }
                    //write the code of finding minimum, better to implement method(s)/class(es)
                    //The user should have the option to choose any of the sortMe... or unsorted... arrays at a time
                    //Do not forget running time measurement
                    break;

                case 3:
                    //use "boolean sorted" in line 35 to prevent being activated before sorting
                    chooseArrayMenu();
                    System.out.println("");

//                    System.out.println("I'll write the code to find how many times a specific number is repeated in the chosen array");
                    switch (myScanner.nextInt()) {
                        case 1:
                            long startTime10 = System.nanoTime();
                            System.out.println("Sorted array containing 100 integers");
                            System.out.println("Enter an integer to find the ocuurrences ");                           
                            x = myScanner.nextInt();
                            System.out.println("The number of occurrence is " + f.countOccurencesHundred(sortMeHundredArr, x));
                            long estimatedTime10 = System.nanoTime() - startTime10;
                            System.out.println("The running time is " + estimatedTime10 + "  nanoseconds ");
                            break;
                        case 2:
                            long startTime11 = System.nanoTime();
                            System.out.println("Sorted array containing 10,000 integers ");
                            System.out.println("Enter an integer to find the ocuurrences ");
                            x = myScanner.nextInt();
                            System.out.println("The number of occurences is " + f.countOccurencesTenthousand(sortMeTenThousandArr, x));
                            long estimatedTime11 = System.nanoTime() - startTime11;
                            System.out.println("The running time is " + estimatedTime11 + "  nanoseconds ");
                            break;
                        case 3:
                            long startTime12 = System.nanoTime();
                            System.out.println("Sorted arrray containing 1,000,000 integers ");
                            System.out.println("Enter an integer to find the ocuurrences ");
                            x = myScanner.nextInt();
                            System.out.println("The number of occurences is " + f.countOccurencesMillion(sortMeMillionArr, x));
                            long estimatedTime12 = System.nanoTime() - startTime12;
                            System.out.println("The running time is " + estimatedTime12 + "  nanoseconds ");
                            break;
                        case 4:
                            long startTime13 = System.nanoTime();
                            System.out.println("Unorted arrray containing 100 integers ");
                            System.out.println("Enter an integer to find the ocuurrences ");
                            x = myScanner.nextInt();
                            System.out.println("The number of occurences is " + ff.countOccurencesUnsortHundred(unSortedHundredArr, x));
                            long estimatedTime13 = System.nanoTime() - startTime13;
                            System.out.println("The running time is " + estimatedTime13 + "  nanoseconds ");
                            break;

                        case 5:
                            long startTime14 = System.nanoTime();
                            System.out.println("Unorted arrray containing 10000 integers ");
                            System.out.println("Enter an integer to find the ocuurrences ");
                            x = myScanner.nextInt();
                            System.out.println("The number of occurences is " + ff.countOccurencesUnsortTenThousand(unSortedTenThousandArr, x));
                            long estimatedTime14 = System.nanoTime() - startTime14;
                            System.out.println("The running time is " + estimatedTime14 + "  nanoseconds ");
                            break;
                        case 6:
                            long startTime15 = System.nanoTime();
                            System.out.println("Unorted arrray containing 1,000,000 integers ");
                            System.out.println("Enter an integer to find the ocuurrences ");
                            x = myScanner.nextInt();
                            System.out.println("The number of occurences is " + ff.countOccurencesUnsortMillion(unSortedMillionArr, x));
                            long estimatedTime15 = System.nanoTime() - startTime15;
                            System.out.println("The running time is " + estimatedTime15 + "  nanoseconds ");
                            break;
                    }
                    //Write the code of finding number of occurrences, better to implement method(s)/class(es)
                    //The user should have the option to choose any of the sortMe... or unsorted...  arrays at a time
                    //Do not forget running time measurement
                    break;

                case 4:
                    //use "boolean sorted" in line 36 to prevent being activated before sorting
                    chooseArrayMenu();

//                    System.out.println("I'll write the code to print out the content of a chosen array");
//                    System.out.println("Array with one million integers may take long time to print out");
                    switch (myScanner.nextInt()) {
                        case 1:
                            f.sortHundred(sortMeHundredArr);
                            for (int i = 0; i < sortMeHundredArr.length; i++) {

                                System.out.println(sortMeHundredArr[i]);
                            }
                            System.out.println("**print completed**");
                            break;
                        case 2:
                            f.sortTenThousand(sortMeTenThousandArr);
                            for (int i = 0; i < sortMeTenThousandArr.length; i++) {

                                System.out.println(sortMeTenThousandArr[i]);
                            }
                            System.out.println("**print completed**");
                            break;
                        case 3:
                            f.sortMillion(sortMeMillionArr);
                            for (int i = 0; i < sortMeMillionArr.length; i++) {

                                System.out.println(sortMeMillionArr[i]);
                            }
                            System.out.println("**print completed**");
                            break;
                        case 4:

                            for (int i = 0; i < unSortedHundredArr.length; i++) {

                                System.out.println(unSortedHundredArr[i]);
                            }
                            System.out.println("**print completed**");
                            break;
                        case 5:
                            for (int i = 0; i < unSortedTenThousandArr.length; i++) {

                                System.out.println(unSortedTenThousandArr[i]);
                            }
                            System.out.println("**print completed**");
                            break;
                        case 6:
                            for (int i = 0; i < unSortedMillionArr.length; i++) {

                                System.out.println(unSortedMillionArr[i]);
                            }
                            System.out.println("**print completed**");
                            break;




                    }
                    break;

                case 5:
                    System.out.println("Welcome back");
                    System.exit(0);
                    break;

                default:
                    System.out.println("The input is out of range");
                    break;
            } //End of switch
        } //End of while loop
    } //End of myMainMethod method

    private String printArray() {

        return null;

        //Null should be changed by you
    } //End of printArray method

    public static void main(String[] args) {
        //One easy way to get rid of static keyword in main method
        Main m1 = new Main();
        m1.myMainMethod();

    }

    private void fillAllArrays() {

        writeToArrayFromFile("million.txt", sortMeHundredArr);
        writeToArrayFromFile("million.txt", sortMeTenThousandArr);
        writeToArrayFromFile("million.txt", sortMeMillionArr);

        writeToArrayFromFile("million.txt", unSortedHundredArr);
        writeToArrayFromFile("million.txt", unSortedTenThousandArr);
        writeToArrayFromFile("million.txt", unSortedMillionArr);
    } //End of fillAllArrays method

    public void writeToArrayFromFile(String fileName, int[] inputArr) {
        int temp = inputArr.length;
        String s;
        try {
            BufferedReader b = new BufferedReader(new InputStreamReader(new FileInputStream(fileName)));
            while (temp > 0) {
                s = b.readLine();
                if (s == null) {
                    break;
                }
                inputArr[inputArr.length - temp--] = Integer.parseInt(s);
            }//End of try
            b.close();
        } catch (IOException ex) {
            System.out.println(ex.getMessage());
        }  //End of catch
    }//End of writeToArrayFromFile method

    private void chooseArrayMenu() {
        System.out.println("Enter a number between 1 to 6");

        System.out.println("1. Sorted array containing 100 integers");
        System.out.println("2. Sorted array containing 10,000 integers");
        System.out.println("3. Sorted array containing 1,000,000 integers");
        System.out.println("4. Unsorted array containing 100 integers");
        System.out.println("5. Unsorted array containing 10,000 integers");
        System.out.println("6. Unsorted array containing 1,000,000 integers");

    } //End of chooseArrayMenu

    private void printMenu() {
        if (firstTime) {
            System.out.println("\n\n***** Welcome to our application *****");
            System.out.println("******* Please follow the menu *******");
            System.out.println("\n**** Main menu ****");

            System.out.println("Select 1 or 5");
            System.out.println("1. Sort");
            System.out.println("2. (Unavailabe before sorting) Find minimum");
            System.out.println("3. (Unavailabe before sorting) Find number of occurrences");
            System.out.println("4. (Unavailabe before sorting) Print out one array");
            System.out.println("5. Quit");
        } //End of if
        else {
            System.out.println("\n**** Main menu ****");
            System.out.println("select a number between 1 to 5");
            System.out.println("1. Sort");
            System.out.println("2. Find minimum");
            System.out.println("3. Find number of occurrences");
            System.out.println("4. Print out one array");
            System.out.println("5. Quit");

        } //End of else
    } //End of printMenu method
}
